package network

import (
	"bytes"
	"encoding/binary"
)

const (
	PkgLen    = 4
	EveryRead = 2
)

// 将数据包编码（即加上包头在转为二进制）
func Encode(msg []byte) ([]byte, error) {
	//获取发送数据的长度，并转换成两个字节长度，即uint16
	lenPkg := uint32(len(msg))
	//创建数据包
	dataPkg := new(bytes.Buffer) //使用字节缓冲区，一步步写入性能更高

	//先向缓冲区写入包头
	//大小端口诀：大端：尾端在高位 小端：尾端在低位
	//编码用小端写入，解码也要从小端读取，要保持一致
	err := binary.Write(dataPkg, binary.LittleEndian, lenPkg) //往存储空间小端写入数据
	if err != nil {
		return nil, err
	}
	//写入消息
	err = binary.Write(dataPkg, binary.LittleEndian, msg)
	if err != nil {
		return nil, err
	}
	return dataPkg.Bytes(), nil
}

// 解码数据包
func Decode(conn *NetConn) ([][]byte, error) {
	bData := make([][]byte, 0)
	for {
		//读取数据包的长度(从包头读取)
		if PkgLen >= len(conn.msgBuffer.readBuff) {
			return bData, nil
		}
		lenByte := conn.msgBuffer.readBuff[:PkgLen] //读取前两个字节的数据

		//转成Buffer对象，设置为小端读取
		buff := bytes.NewBuffer(lenByte)

		var lenPkg uint16                                      //读取的数据大小，初始化为0
		err := binary.Read(buff, binary.LittleEndian, &lenPkg) //从小端读取
		if err != nil {
			return bData, err
		}
		//读取消息
		pkg := make([]byte, int(lenPkg)+PkgLen)
		//Buffered返回缓冲区中现有的可读取的字节数
		if len(conn.msgBuffer.readBuff) < int(lenPkg)+PkgLen {
			return bData, nil
		} else {
			pkg = conn.msgBuffer.readBuff[:int(lenPkg)+PkgLen]
			conn.msgBuffer.readBuff = conn.msgBuffer.readBuff[int(lenPkg)+PkgLen:]
		}
		bData = append(bData, pkg[PkgLen:])
	}
}
